home *** CD-ROM | disk | FTP | other *** search
/ Libris Britannia 4 / science library(b).zip / science library(b) / MEDICAL / H121A.ZIP / FILES6.EXE / lha / ENTFACE.PAS < prev    next >
Pascal/Delphi Source File  |  1991-07-15  |  12KB  |  387 lines

  1. {$R-}    {Range checking off}
  2. {$B+}    {Boolean complete evaluation on}
  3. {$S+}    {Stack checking on}
  4. {$I+}    {I/O checking on}
  5. {$N+}    {No numeric coprocessor}
  6. {$E+}    {Emulation on}
  7. {$V-}    {No string type checking}
  8. Unit EntFace;
  9. {This unit provides routines for any Turbo Pascal (version 5) program
  10.  to install a vector to it's entry point at interrupt 75, and to
  11.  access the data structures FieldList and FieldRecord.  These form
  12.  a linked list of information about all fields in the current
  13.  questionnaire in ENTER.  The routines FindField, GetString, GetNumber,
  14.  PutString, and PutNumber allow access to the FieldList record for
  15.  a named field, and transfer values from (Get) and to (Put) the
  16.  questionnaire field in ENTER.}
  17.  
  18.   Interface
  19.  
  20.     Uses
  21.       Crt, Dos;
  22.  
  23.     Type
  24.       Float = Double; { 8 byte real, requires 8087 math chip, or
  25.                         software emulation }
  26.  
  27.     const
  28.       TNNearlyZero = 1E-015;
  29.       Infinity     = 1E+50;
  30.       RealSize     = 8;
  31.       EnterError   = 1;
  32.  
  33.   Type
  34.     String80    = String [80];
  35.     String20    = String [20];
  36.     Alfa        = Packed Array [1 .. 10] of Char;
  37.     Byte        = 0 .. 255;
  38.     EntryType   = (Numeric, Alpha, Date, Uppercase, CheckBox, YesNo,
  39.                    RealNum, PhoneNum, Time, LocalNum, TodayType, EuroDate,
  40.                    IDNum, Res4, Res5);
  41.     ValueRecord = Packed Record
  42.                     Case Integer of
  43.                       0: (IntVal  : Integer);
  44.                       1: (RealVal : Float);
  45.                       2: (StrVal  : String20)
  46.                   End (*ValueRecord*);
  47.     LegalPtr    = ^ LegalRecord;
  48.     LegalRecord = Packed Record
  49.                     Value      : ValueRecord;
  50.                     NewValue   : ValueRecord;
  51.                     IsNew      : Boolean;
  52.                     Next       : LegalPtr
  53.                   End (*LegalRecord*);
  54.     FieldPtr    = ^ FieldList;
  55.     FieldRecord = Record
  56.                     EntryKind  : EntryType;
  57.                     EntryLen   : Byte (* 0 means no entry for this field *);
  58.                     Name       : Alfa;
  59.                     MustEnter  : Boolean;
  60.                     Repeated   : Boolean;
  61.                     QuestionX  : Byte;
  62.                     QuestionY  : Integer;
  63.                     QuestionC  : Byte;
  64.                     EntryX     : Byte;
  65.                     EntryY     : Integer;
  66.                     EntryColor : Byte;
  67.                     FieldChar  : Char;
  68.                     Hidden     : Boolean;
  69.                     Decimals   : Byte;
  70.                     HasMin     : Boolean;
  71.                     FieldMin   : ValueRecord;
  72.                     HasMax     : Boolean;
  73.                     FieldMax   : ValueRecord;
  74.                     Legal      : LegalPtr;
  75.                     Jumps      : LegalPtr;
  76.                     Codes      : LegalPtr;
  77.                     CodeField  : FieldPtr;
  78.                     AutoJump   : FieldPtr;
  79.                     BeforeCmds : Pointer;
  80.                     AfterCmds  : Pointer;
  81.                     Question   : String80
  82.                   End;
  83.     FieldList   = Record
  84.                     Previous     : FieldPtr;
  85.                     Next         : FieldPtr;
  86.                     Missing      : Boolean;
  87.                     FieldInt     : Integer;
  88.                     FieldReal    : Float;
  89.                     FieldEntry   : String80;
  90.                     Field        : FieldRecord
  91.                   End;
  92.  
  93.   {The following routines are available for communication between the ENTER
  94.   program and the TSR program written in Turbo Pascal, Version 5}
  95.  
  96.  
  97.   Function FindField (Header : FieldPtr; Field : String) : FieldPtr;
  98.   {Returns a pointer to the FieldList record for the field named in Field}
  99.  
  100.   Function InstallInterrupt (IntNo : Integer; ProcPtr : Pointer) : Integer;
  101.   {Installs an interrupt of the IntNo given.  The interrupt vector will
  102.    be ProcPtr, the entry point of your program}
  103.  
  104.   Function GetString (Header : FieldPtr; QField : String) : String;
  105.   {Returns a string from a field in the questionnaire}
  106.  
  107.   Function GetNumber (Header : FieldPtr; QField : String) : Float;
  108.   {Returns a number from a field in the questionnaire}
  109.  
  110.   Procedure PutString (Header : FieldPtr; QField : String; S : String);
  111.   {Places S in the named questionnaire field}
  112.  
  113.   Procedure PutNumber (Header : FieldPtr; QField : String; R : Float);
  114.   {Places a number, R, in the named questionnaire field}
  115.  
  116.  
  117.   Var
  118.     EnterResult : Integer;
  119.  
  120.   Implementation
  121.  
  122.   Procedure MakeAlfa (S : String80; VAR A : Alfa);
  123.  
  124.     Var
  125.       I : Integer;
  126.  
  127.     Begin
  128.       A := '          ';
  129.       For I := 1 to Length (S) Do
  130.         If I <= 10
  131.         Then
  132.           A [I] := UpCase (S [I])
  133.     End (*MakeAlfa*);
  134.  
  135.   Procedure MakeString (VAR S : String80; A : Alfa);
  136.  
  137.     Var
  138.       I : Integer;
  139.  
  140.     Begin
  141.       S := '';
  142.       For I := 1 to 10 Do
  143.         If A [I] <> ' '
  144.         Then
  145.           S := S + A [I]
  146.     End (*MakeString*);
  147.  
  148. Function FindField (Header : FieldPtr; Field : String) : FieldPtr;
  149. (*********************************************************************
  150.  * FindField returns a pointer to the field having name = FieldName. *
  151.  * If no such field exists in the list pointed to by header then     *
  152.  * NIL is returned.                                                  *
  153.  *********************************************************************)
  154.  
  155.   Var
  156.     FPtr  : FieldPtr;
  157.     Found : Boolean;
  158.     Fieldname : Alfa;
  159.     ch : Char;
  160.     var I : integer;
  161.  
  162.   Begin
  163.     FPtr := Header;
  164.     Found := False;
  165.     MakeAlfa (Field, Fieldname);
  166.       {Convert fieldname to array and pad with spaces to 10 characters}
  167.     Repeat
  168.       If FPtr ^.Field.Name = FieldName
  169.       Then
  170.         Found := True
  171.       Else
  172.         FPtr := FPtr ^.Next
  173.     Until Found or (FPtr = Header);
  174.     If Found
  175.     Then
  176.       FindField := FPtr
  177.     Else
  178.       begin
  179.         FindField := NIL;
  180.         GotoXY (1,25);
  181.         Write
  182.  ('Field ',Field,' not found. Please check TSR program and questionnaire.');
  183.         ch := readkey;
  184.       end;
  185.   End (*FindField*);
  186.  
  187. Function InstallInterrupt (IntNo : Integer; ProcPtr : Pointer) : Integer;
  188.  
  189.     Type
  190.       InterruptRecPtr  = ^ InterruptRec;
  191.       InterruptRec     = Packed Record
  192.                            JmpInst      : Byte;
  193.                            OldInt       : Pointer;
  194.                            IDString     : Array [1 .. 5] of Char;
  195.                            OldDSValue   : Word;
  196.                            EnterRoutine : Pointer
  197.                          End (*InterruptRec*);
  198.  
  199.     Const
  200.       InterruptRoutine : InterruptRec =
  201.                            (JmpInst:      $EA;
  202.                             OldInt:       NIL;
  203.                             IDString:     'ENTER';
  204.                             OldDSValue:   0;
  205.                             EnterRoutine: NIL);
  206.  
  207.     Var
  208.       Dummy : Pointer;
  209.  
  210.     Function GetDSValue : Word;
  211.  
  212.       Inline ($8C/$D8)   {MOV   AX,DS};
  213.  
  214.     Begin
  215.       GetIntVec (IntNo, Dummy);
  216.       If InterruptRecPtr (Dummy) ^.IDString = 'ENTER'
  217.       Then
  218.         InstallInterrupt := 1
  219.       Else
  220.         Begin
  221.           InterruptRoutine.OldInt := Dummy;
  222.           InterruptRoutine.EnterRoutine := ProcPtr;
  223.           InterruptRoutine.OldDSValue := GetDSValue;
  224.           SetIntVec (IntNo, @InterruptRoutine);
  225.           InstallInterrupt := 0
  226.         End (*Else*)
  227.     End (*InstallInterrupt*);
  228.  
  229. Function GetString (Header : FieldPtr; QField : String) : String;
  230.   {Returns a string from a field in the questionnaire}
  231.  Var FPtr : FieldPtr;
  232.  
  233.     Begin
  234.       FPtr := FindField (Header, QField);
  235.       With FPtr ^ Do
  236.         If Missing
  237.         Then
  238.           GetString := ''
  239.         Else
  240.           GetString := FieldEntry
  241.     End (*GetString*);
  242.  
  243. Function GetNumber (Header : FieldPtr; QField : String) : Float;
  244.   {Returns a number from a field in the questionnaire}
  245.  
  246.  Var FPtr : FieldPtr;
  247.  
  248.     Begin
  249.       FPtr := FindField (Header, QField);
  250.       GetNumber := 0;
  251.       With FPtr ^ Do
  252.         If Not Missing
  253.         Then
  254.           Case Field.EntryKind of
  255.             Numeric:
  256.               GetNumber := FieldInt;
  257.             RealNum:
  258.               GetNumber := FieldReal;
  259.             Else
  260.               EnterResult := EnterError
  261.           End (*Case*)
  262.     End (*GetNumber*);
  263.  
  264. Function TruncDecimals (R : Float; NumDecimals : Integer) : Float;
  265.  
  266.     Var
  267.       Temp : Float;
  268.  
  269.     Begin
  270.       Temp := 1;
  271.       While (NumDecimals > 0) Do
  272.         Begin
  273.           Temp := Temp * 10;
  274.           Dec (NumDecimals)
  275.         End (*While*);
  276.       R := Round (R * Temp);
  277.       TruncDecimals := R / Temp
  278.     End (*TruncDecimals*);
  279.  
  280.  
  281. Procedure PutString (Header : FieldPtr; QField : String; S : String);
  282.   {Places S in the named questionnaire field}
  283.  
  284.     Var
  285.       I, J : Integer;
  286.       R    : Float;
  287.       FPtr : FieldPtr;
  288.  
  289.     Begin
  290.       FPtr := FindField (Header, QField);
  291.       With FPtr ^ Do
  292.         If S = ''
  293.         Then
  294.           Begin
  295.             Missing := True;
  296.             FieldEntry := ''
  297.           End (*If*)
  298.         Else
  299.           Begin
  300.             J := 0;
  301.             Case Field.EntryKind of
  302.               Numeric:
  303.                 Begin
  304.                   Val (S, I, J);
  305.                   If J = 0
  306.                   Then
  307.                     PutNumber (Header, QField, I)
  308.                 End (*Numeric*);
  309.               RealNum:
  310.                 Begin
  311.                   Val (S, R, J);
  312.                   If J = 0
  313.                   Then
  314.                     PutNumber (Header, QField, R)
  315.                 End (*RealNum*);
  316.               Else
  317.                 Begin
  318.                   If Length (S) > Field.EntryLen
  319.                   Then
  320.                     S [0] := Chr (Field.EntryLen);
  321.                   FieldEntry := S
  322.                 End (*Else*)
  323.             End (*Case*);
  324.             If J <> 0
  325.             Then
  326.               EnterResult := EnterError
  327.           End (*Else*)
  328.     End (*PutString*);
  329.  
  330.   Function MakeStringFromReal (R : Float; Width : Integer) : String;
  331.  
  332.     Var
  333.       S : String;
  334.       SLen : Byte Absolute S;
  335.  
  336.     Begin
  337.       Str (R: Width*2: Width, S);
  338.       While (S [SLen] = '0') Do
  339.         Dec (SLen);
  340.       If S [SLen] = '.'
  341.       Then
  342.         Dec (SLen);
  343.       While (S [1] = ' ') And (SLen > 0) Do
  344.         Delete (S, 1, 1);
  345.       MakeStringFromReal := S
  346.     End (*MakeStringFromReal*);
  347.  
  348.  
  349. Procedure PutNumber (Header : FieldPtr; QField : String; R : Float);
  350.   {Places a number, R, in the named questionnaire field}
  351.  
  352.  
  353.     Var
  354.       I : Integer;
  355.    FPtr : FieldPtr;
  356.  
  357.     Begin
  358.       FPtr := FindField (Header, QField);
  359.       With FPtr ^ Do
  360.         Begin
  361.           Missing := False;
  362.           Case Field.EntryKind of
  363.             Numeric:
  364.               Begin
  365.                 I := Round (R);
  366.                 Str (I: Field.EntryLen, FieldEntry);
  367.                 FieldInt := I;
  368.               End (*Numeric*);
  369.             RealNum:
  370.               begin
  371.                 If Field.Decimals > 0 Then
  372.                   Begin
  373.                     R := TruncDecimals (R, Field.Decimals);
  374.                     Str (R: Field.EntryLen: Field.Decimals, FieldEntry)
  375.                   End (*If*)
  376.                 Else
  377.                   FieldEntry := MakeStringFromReal (R, Field.EntryLen);
  378.                 FieldReal := R;
  379.               end;
  380.             Else
  381.               FieldEntry := MakeStringFromReal (R, Field.EntryLen)
  382.           End (*Case*)
  383.         End (*With*)
  384.     End (*PutNumber*);
  385.  
  386. End.  (*ENTFACE.PAS*)
  387.